﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;

using System.Device.Location;

using Microsoft.Phone.Controls.Maps;
using Microsoft.Phone.Controls.Maps.Core;
using System.Windows.Navigation;
using NerdDinnerDataBound.NerdDinnerServiceReference1;
using NerdDinnerDataBound.Models;
using System.Collections.ObjectModel;

namespace NerdDinnerDataBound
{
    public partial class MapPage : PhoneApplicationPage
    {

        Dinner selectedItem;

        //public MapPage()
        //{
        //    InitializeComponent();
        //}


        // When page is navigated to set data context to selected item in list
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            string selectedIndex = "";
            if (NavigationContext.QueryString.TryGetValue("selectedItem", out selectedIndex))
            {
                int index = int.Parse(selectedIndex);
                //DataContext = App.ViewModel.Dinners[index];
                //selectedItem = (Dinner)DataContext;
                selectedItem = (Dinner)App.ViewModel.Dinners[index];
                //Center = new GeoCoordinate(selectedItem.Latitude, selectedItem.Longitude);
               // Map.Center = Center;
                CreateDinnerPushpin(selectedItem);

            }


        }

        #region Consts

        /// <value>Default map zoom level.</value>
        private const double DefaultZoomLevel = 18.0;

        /// <value>Maximum map zoom level allowed.</value>
        private const double MaxZoomLevel = 21.0;

        /// <value>Minimum map zoom level allowed.</value>
        private const double MinZoomLevel = 1.0;

        #endregion

        #region Fields

        /// <value>Provides credentials for the map control.</value>
        private readonly CredentialsProvider _credentialsProvider = new ApplicationIdCredentialsProvider(App.Id);

        /// <value>Default location coordinate.</value>
        private static readonly GeoCoordinate DefaultLocation = new GeoCoordinate(47.639631, -122.127713);

        /// <value>Collection of pushpins available on map.</value>
        private readonly ObservableCollection<PushpinModel> _pushpins = new ObservableCollection<PushpinModel>
        {
            new PushpinModel
            {
                Location = DefaultLocation,
                Icon = new Uri("/Resources/Icons/Pushpins/PushpinLocation.png", UriKind.Relative)
            }
        };

        /// <value>Map zoom level.</value>
        private double _zoom;

        /// <value>Map center coordinate.</value>
        private GeoCoordinate _center;

        #endregion

        #region Properties

        public bool HasDirections
        {
            get
            {
                // TODO : Return true only if has directions.

                return true;
            }
        }

        /// <summary>
        /// Gets the credentials provider for the map control.
        /// </summary>
        public CredentialsProvider CredentialsProvider
        {
            get { return _credentialsProvider; }
        }

        /// <summary>
        /// Gets or sets the map zoom level.
        /// </summary>
        public double Zoom
        {
            get { return _zoom; }
            set
            {
                var coercedZoom = Math.Max(MinZoomLevel, Math.Min(MaxZoomLevel, value));
                if (_zoom != coercedZoom)
                {
                    _zoom = value;
                    NotifyPropertyChanged("Zoom");
                }
            }
        }

        /// <summary>
        /// Gets or sets the map center location coordinate.
        /// </summary>
        public GeoCoordinate Center
        {
            get { return _center; }
            set
            {
                if (_center != value)
                {
                    _center = value;
                    NotifyPropertyChanged("Center");
                }
            }
        }

        /// <summary>
        /// Gets a collection of pushpins.
        /// </summary>
        public ObservableCollection<PushpinModel> Pushpins
        {
            get { return _pushpins; }
        }

        #endregion

        #region Tasks

        private void InitializeDefaults()
        {
            // TODO : Initialize default properties.
        }

        private void ChangeMapMode()
        {
            // TODO : Change map view mode.
            if (Map.Mode is AerialMode)
            {
                Map.Mode = new RoadMode();
            }
            else
            {
                Map.Mode = new AerialMode(true);
            }
        }

        private void CenterLocation()
        {
            // Center map to default location.
            Center = DefaultLocation;

            // Reset zoom default level.
            Zoom = DefaultZoomLevel;
        }

        private void CenterPushpinsPopup(Point touchPoint)
        {
            // Reposition the pushpins popup to the center of the touch point.
            Canvas.SetTop(PushpinPopup, touchPoint.Y - ListBoxPushpinCatalog.Height / 2);
        }

        private void CreateDinnerPushpin(Dinner selected)
        {
            GeoCoordinate location = new GeoCoordinate(selectedItem.Latitude, selectedItem.Longitude);
            var pushpinPrototype = new PushpinModel(); // selectedItem as PushpinModel;
            var pushpin = pushpinPrototype.Clone(location);
            pushpin.TypeName = "PushpinRestaurant";
            pushpin.Icon = new Uri("/Resources/Icons/Pushpins/PushpinRestaurant.png", UriKind.Relative);
            Pushpins.Add(pushpin);
        }

        private void CreateNewPushpin(object selectedItem, Point point)
        {
            // Translate the map viewport touch point to a geo coordinate.
            GeoCoordinate location;
            Map.TryViewportPointToLocation(point, out location);

            // Use the geo coordinate calculated to add a new pushpin,
            // based on the selected pushpin prototype,
            var pushpinPrototype = selectedItem as PushpinModel;
            var pushpin = pushpinPrototype.Clone(location);
            
            Pushpins.Add(pushpin);
        }

        private void Pushpin_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            var pushpin = sender as Pushpin;

            // Center the map on a pushpin when touched.
            Center = pushpin.Location;
        }

        private void CalculateRoute()
        {
            // TODO : Calculate a route.
        }

        #endregion                

    }
}